#include "pragmaHandler.hpp"

#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Attr.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Sema/Sema.h"

using namespace clang;
using namespace llvm;

bool wafer_guard::WaferParallelStat = false;
llvm::SmallVector<const IdentifierInfo*, 2> wafer_guard::ArgsToEnclosed = {};
llvm::SmallVector<unsigned> wafer_guard::pragmaLineNumber{0};

namespace {

void WaferPragma::HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &PragmaTok)
{
    wafer_guard::ArgsToEnclosed.clear();

    Token Tok;
    PP.Lex(Tok);
    auto FirstArgTok = Tok.getIdentifierInfo()->getName();

    while (Tok.isNot(tok::eod)) {
      if (auto *II = Tok.getIdentifierInfo()) {
        wafer_guard::ArgsToEnclosed.push_back(II);
      }
      PP.Lex(Tok);
    }

    if (FirstArgTok == "parallel") {
      SourceLocation PragmaLoc = PragmaTok.getLocation();
      unsigned PragmaLine = PP.getSourceManager().getSpellingLineNumber(PragmaLoc);
      wafer_guard::pragmaLineNumber.push_back(PragmaLine);
      wafer_guard::WaferParallelStat = true;
    }
}

} // namespace

void addPragmaWaferHandlers(clang::Preprocessor &PP) 
{
  PP.AddPragmaHandler(new WaferPragma());
}

